package com.nineclock.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.aliyun.oss.OSS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.nineclock.common.constant.NcConstant;
import com.nineclock.common.constant.SMSConstant;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.oss.OssProperties;
import com.nineclock.common.threadlocal.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.common.utils.UUIDUtils;
import com.nineclock.message.enums.MessageTypeEnum;
import com.nineclock.message.pojo.NcMessage;
import com.nineclock.system.config.HxImManager;
import com.nineclock.system.dto.SysAllowedJoinCompanyUserDTO;
import com.nineclock.system.dto.SysApplyJoinCompanyUserDTO;
import com.nineclock.system.dto.SysChangeMainManagerDTO;
import com.nineclock.system.dto.SysCompanyDTO;
import com.nineclock.system.mapper.*;
import com.nineclock.system.pojo.*;
import com.nineclock.system.service.SMSService;
import com.nineclock.system.service.SysCompanyService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 黑马程序员
 * @Company http://www.ithiema.com
 * @Version 1.0
 */
@Service
@Slf4j
public class SysCompanyServiceImpl implements SysCompanyService {

    @Autowired
    SysCompanyMapper companyMapper;


    @Override
    public SysCompanyDTO queryCompanyInfo() {
        //获取企业id
        Long companyId = CurrentUserHolder.get().getCompanyId();

        //获取企业信息
        SysCompany company = companyMapper.selectById(companyId);
        if(company == null){
            throw new NcException(ResponseEnum.COMPANY_NOT_FOUND);
        }

        return BeanHelper.copyProperties(company, SysCompanyDTO.class);
    }

    @Autowired
    OSS oss;

    @Autowired
    OssProperties ossProperties;

    @Override
    public String uploadOSS(MultipartFile file) throws IOException {
        //健壮性判断
        if(file == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        //判断文件的类型
        String type = file.getContentType();
        if(! NcConstant.ALLOWED_IMG_TYPES.contains(type)){
            throw new NcException(ResponseEnum.INVALID_FILE_TYPE);
        }

        //判断文件的大小
        long size = file.getSize();
        if(size > NcConstant.maxFileSize){
            throw new NcException(ResponseEnum.FILE_SIZE_EXCEED_MAX_LIMIT);
        }

        //生成一个唯一的文件名称
        //uuid
        String uuid = UUIDUtils.getUUID();
        //文件的后缀
        String originalFilename = file.getOriginalFilename();//获取原始文件名
        //截取后缀名
        String extendName = originalFilename.substring(originalFilename.lastIndexOf("."));
        //key uuid + 文件后缀
        String key = uuid + extendName;
        oss.putObject(ossProperties.getBucketName(), key, file.getInputStream());

        //获取文件的完整路径
        String imgPath = String.format(ossProperties.getHost(), ossProperties.getBucketName()) + key;

        return imgPath;
    }

    @Override
    public void updateCompanyInfo(SysCompanyDTO companyDTO) {
        if(companyDTO == null || companyDTO.getName() == null || companyDTO.getLogo() == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //获取企业id
        Long companyId = CurrentUserHolder.get().getCompanyId();

        //获取企业信息
        SysCompany company = companyMapper.selectById(companyId);
        if(company == null){
            throw new NcException(ResponseEnum.COMPANY_NOT_FOUND);
        }
        //更新字段
        company.setName(companyDTO.getName());
        company.setLogo(companyDTO.getLogo());
        //更新到数据
        companyMapper.updateById(company);
    }

    @Autowired
    SysRoleMapper roleMapper;

    @Autowired
    SysCompanyUserRoleMapper companyUserRoleMapper;

    @Autowired
    SMSService smsService;

    @Autowired
    SysCompanyUserMapper companyUserMapper;

    @Override
    public void changeAdmin(SysChangeMainManagerDTO changeMainManagerDTO) {
        if(changeMainManagerDTO == null || changeMainManagerDTO.getCode() == null || changeMainManagerDTO.getUserId() == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }


        // 新管理员的（柳岩）员工id
        Long userId = changeMainManagerDTO.getUserId();

        SysCompanyUser companyUser = companyUserMapper.selectById(userId);
        Boolean flag = smsService.verify(companyUser.getMobile(), changeMainManagerDTO.getCode(), SMSConstant.SMS_TYPE_CHANGE_MANAGER);
        if(!flag){
            throw new NcException(ResponseEnum.CODE_IMAGE_ERROR);
        }
        //获取企业id
        Long companyId = CurrentUserHolder.get().getCompanyId();

        //获取 主管理员 角色id
        LambdaQueryWrapper<SysRole> wrapper  = new LambdaQueryWrapper<>();
        wrapper.eq(SysRole::getRoleName, "ROLE_ADMIN_SYS");
        wrapper.eq(SysRole::getCompanyId, companyId);
        SysRole role = roleMapper.selectOne(wrapper);
        if(role == null){
            throw new NcException(ResponseEnum.ROLE_NOT_FOUND);
        }

        LambdaQueryWrapper<SysCompanyUserRole> companyUserRoleQw = new LambdaQueryWrapper<>();
        companyUserRoleQw.eq(SysCompanyUserRole::getCompanyId, companyId);
        companyUserRoleQw.eq(SysCompanyUserRole::getRoleId, role.getId());
        //员工和角色的关系对象
        SysCompanyUserRole companyUserRole = companyUserRoleMapper.selectOne(companyUserRoleQw);
        if(companyUserRole == null){
            throw new NcException(ResponseEnum.ERROR);
        }


        companyUserRole.setCompanyUserId(userId);

        companyUserRoleMapper.update(companyUserRole, companyUserRoleQw);
    }

    @Override
    public List<SysCompanyDTO> queryCompanyByName(String keyword) {
        LambdaQueryWrapper<SysCompany> wrapper = new LambdaQueryWrapper<>();
        if(keyword != null){
            wrapper.like(SysCompany::getName, keyword);
        }

        List<SysCompany> companyList = companyMapper.selectList(wrapper);
        if(CollectionUtil.isEmpty(companyList)){
            throw new NcException(ResponseEnum.COMPANY_NOT_FOUND);
        }
        return BeanHelper.copyWithCollection(companyList, SysCompanyDTO.class);
    }

    @Autowired
    SysUserMapper userMapper;

    @Autowired
    RocketMQTemplate rocketMQTemplate;

    @Autowired
    HxImManager hxImManager;

    /**
     * 加入企业后，成员企业的员工
     * 1. 更新用户信息
     * 2. 新增员工信息
     * @param sysApplyJoinCompanyUserDTO
     */
    @Override
    public void applyJoinCompany(SysApplyJoinCompanyUserDTO sysApplyJoinCompanyUserDTO) {
        if(sysApplyJoinCompanyUserDTO == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        //根据用户id获取用户信息
        SysUser user = userMapper.selectById(sysApplyJoinCompanyUserDTO.getUserId());
        if(user == null){
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }

        user.setUsername(sysApplyJoinCompanyUserDTO.getUserName());
        user.setEmail(sysApplyJoinCompanyUserDTO.getEmail());
        user.setUpdateTime(new Date());
        user.setLastLoginCompanyId(sysApplyJoinCompanyUserDTO.getCompanyId());
        //更新到数据库
        userMapper.updateById(user);

        //创建员工 数据
        SysCompanyUser companyUser = new SysCompanyUser();
        companyUser.setRemark(sysApplyJoinCompanyUserDTO.getApplyReason()); //申请加入的理由
        companyUser.setPost(sysApplyJoinCompanyUserDTO.getPost()); //职位
        companyUser.setTimeEntry(new Date());//入职时间
        companyUser.setEmail(sysApplyJoinCompanyUserDTO.getEmail());//邮箱
        companyUser.setMobile(sysApplyJoinCompanyUserDTO.getMobile());//手机号码
        companyUser.setCreateTime(new Date());//创建时间
        companyUser.setEnable((short)0);//是否可用， 管理员审批之后，可用
        companyUser.setCompanyName(sysApplyJoinCompanyUserDTO.getCompanyName());//企业名称
        companyUser.setCompanyId(sysApplyJoinCompanyUserDTO.getCompanyId()); //企业id
        companyUser.setUserId(sysApplyJoinCompanyUserDTO.getUserId());//用户id
        companyUser.setUserName(sysApplyJoinCompanyUserDTO.getUserName());//用户名
        companyUser.setImageUrl(sysApplyJoinCompanyUserDTO.getImageUrl()); //图片地址

        companyUserMapper.insert(companyUser);

        //获取 系统主管理员
        SysCompanyUser currentAdmin = companyUserMapper.getCurrentAdmin(sysApplyJoinCompanyUserDTO.getCompanyId());
        // 推送消息 给主管理员
        NcMessage message = new NcMessage();
        message.setMessageType(MessageTypeEnum.COMPANY_APPLY.getType()); // 消息类型
        message.setAudience(MessageTypeEnum.COMPANY_APPLY.getAudience()); // 根据别名推送
        message.setTitle(MessageTypeEnum.COMPANY_APPLY.getTitle());//消息的标题
        message.setCreateTime(new Date());
        message.setCompanyId(sysApplyJoinCompanyUserDTO.getCompanyId() + "");
        message.setContent(sysApplyJoinCompanyUserDTO.getUserName() + " 正在申请加入企业，请及时审批"); //消息内容
        message.setUseStatus(0); //是否已经使用
        message.setTargets(Arrays.asList(currentAdmin.getMobile())); //目标人手机号码
        message.setApproveStatue(0); //审批状态
        message.setApplyUserId(sysApplyJoinCompanyUserDTO.getUserId()); //申请人 用户id
        message.setApplyUsername(sysApplyJoinCompanyUserDTO.getUserName()); //申请人用户名
        message.setApproveUserId(currentAdmin.getUserId()); //审批人用户id
        message.setApproveUsername(currentAdmin.getUserName());//审批人用户名

        rocketMQTemplate.convertAndSend( "messagePushTopic", message );


        //把用户信息注册到环信
        SysUser user1 = new SysUser();
        user1.setUsername(sysApplyJoinCompanyUserDTO.getUserName());
        user1.setPassword("123456");

        hxImManager.registerUser2HuanXing(user1);
    }

    @Override
    public void allowJoinCompany(SysAllowedJoinCompanyUserDTO allowedJoinCompanyUserDTO) {
        //1.健壮性判断
        if(allowedJoinCompanyUserDTO == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }
        //2. 更新员工信息
        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysCompanyUser::getUserId, allowedJoinCompanyUserDTO.getApplyUserId());
        wrapper.eq(SysCompanyUser::getCompanyId, CurrentUserHolder.get().getCompanyId());
        //根据userId获取 员工信息
        SysCompanyUser companyUser = companyUserMapper.selectOne(wrapper);

        companyUser.setRemark(allowedJoinCompanyUserDTO.getRemark());
        if(allowedJoinCompanyUserDTO.getApproved()){
            companyUser.setEnable((short)1);
        }
        //更新到数据库
        companyUserMapper.updateById(companyUser);

        //3. 推送消息（推送消息给申请人， 更新mongo）

        rocketMQTemplate.convertAndSend("allowedJoinCompanyTopic", allowedJoinCompanyUserDTO.getNotifyMsgId());

        NcMessage message = new NcMessage();
        message.setMessageType(MessageTypeEnum.COMPANY_APPROVE.getType()); // 消息类型
        message.setAudience(MessageTypeEnum.COMPANY_APPROVE.getAudience()); // 根据别名推送
        message.setTitle(MessageTypeEnum.COMPANY_APPROVE.getTitle());//消息的标题
        message.setCreateTime(new Date());
        message.setCompanyId(CurrentUserHolder.get().getCompanyId() + "");
        if (allowedJoinCompanyUserDTO.getApproved()){
            message.setContent("恭喜您，审核通过!"); //消息内容
        }else{
            message.setContent("很遗憾，审核失败!"); //消息内容
        }
        message.setUseStatus(1); //是否已经使用
        message.setTargets(Arrays.asList(companyUser.getMobile())); //目标人手机号码
        message.setApproveStatue(1); //审批状态
        message.setApplyUserId(companyUser.getUserId()); //申请人 用户id
        message.setApplyUsername(companyUser.getUserName()); //申请人用户名
        message.setApproveUserId(CurrentUserHolder.get().getId()); //审批人用户id
        message.setApproveUsername(CurrentUserHolder.get().getUsername());//审批人用户名

        rocketMQTemplate.convertAndSend("messagePushTopic", message);

    }

    @Override
    public List<SysCompanyDTO> queryCompanyListByUserId(Long userId) {
        if(userId == null){
            throw new NcException(ResponseEnum.INVALID_PARAM_ERROR);
        }

        LambdaQueryWrapper<SysCompanyUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysCompanyUser::getUserId , userId);
        wrapper.eq(SysCompanyUser::getEnable, 1);

        List<SysCompanyUser> companyUserList = companyUserMapper.selectList(wrapper);

        if(CollectionUtil.isEmpty(companyUserList)){
            throw new NcException(ResponseEnum.USER_NOT_JOIN_COMPANY);
        }

        List<Long> companyIds = companyUserList.stream().map(sysCompanyUser -> {
            return sysCompanyUser.getCompanyId();
        }).collect(Collectors.toList());
        
        LambdaQueryWrapper<SysCompany> companyQw = new LambdaQueryWrapper<>();
        companyQw.in(SysCompany::getId, companyIds);

        List<SysCompany> companyList = companyMapper.selectList(companyQw);

        return BeanHelper.copyWithCollection(companyList, SysCompanyDTO.class);
    }
}
